#coding:utf-8

import Config;
import wx;
import os;
import wx.lib.rcsizer as rcs;
import wx.lib.intctrl;
import Global;
import Loading;
import string;
import ELog;
import traceback;
import array;
import time;
import numpy;  
import matplotlib;
import matplotlib.figure;
import matplotlib.backends.backend_wxagg;
import matplotlib.backends.backend_wx;
from mpl_toolkits.axes_grid1.axes_divider import make_axes_area_auto_adjustable;
import math;

try:
    from agw import fourwaysplitter as FWS
except ImportError: # if it's not there locally, try the wxPython lib.
    try:
        import wx.lib.agw.fourwaysplitter as FWS
    except ImportError:
        exit()

#菜单ID
from AppIds import *

import SerialUtil
import wx.lib.newevent

#Frame start
SERIAL_GENIUS_FS_CHAR=0x0F;
#Slash
SERIAL_GENIUS_SL_CHAR=0x1F;


ANGLE_EMPTY = -999999
DEBUG = False;

#Rehoo金属探测
class Rehoodetector(wx.Panel):
    def __init__(self, parent):
        wx.Panel.__init__(self, parent, style=wx.BORDER_DOUBLE);

        ############# 状态信息 ############
        #该模块是否启用
        self.isUsing=False;
        self.changed = False;
        self.autoScale=True;

        ############# 配置信息 ############
        self.dataBuffer=[];
        
        self.refreshTimer = wx.Timer(self);
        self.Bind(wx.EVT_TIMER, self.PlotData);
        self.refreshTimer.Start(500)
        
        ############# 开始布局 ###########
        gridSizer = rcs.RowColSizer();
        rowTotal=4;
        colTotal=6;

        #标题
        title=wx.StaticText(self, -1, u"金属探测");
        title.SetFont(wx.Font(8, wx.FONTFAMILY_DEFAULT, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_BOLD ));
        gridSizer.Add(title, pos=(0,0), size=(1, colTotal), flag=wx.EXPAND|wx.ALIGN_CENTER_VERTICAL);

        #绘图区
        self.figure=matplotlib.figure.Figure(figsize=(1,1));
        self.figure.subplots_adjust(left=0.00, bottom=0.00, right=1.00, top=1.00, wspace=None, hspace=None);
        self.axes=self.figure.add_subplot(111);
        self.canvas = matplotlib.backends.backend_wxagg.FigureCanvasWxAgg(self, 20, self.figure);
        gridSizer.Add(self.canvas, pos=(1,0), size=(1, colTotal), flag=wx.EXPAND|wx.ALIGN_CENTER_VERTICAL);
        make_axes_area_auto_adjustable(self.axes);
        self.canvas.mpl_connect('button_press_event', self.on_button_press_event);    

        
        #清空
        btn = wx.Button(self, -1, u"清空")
        self.Bind(wx.EVT_BUTTON, self.OnClearData, btn);
        gridSizer.Add(btn, pos=(2, 0), size=(1,1), flag=wx.ALIGN_CENTER_VERTICAL);
        
        
        btn = wx.Button(self, -1, u"更新")
        self.Bind(wx.EVT_BUTTON, self.OnUpdateData, btn);
        gridSizer.Add(btn, pos=(2, 1), size=(1,1), flag=wx.ALIGN_CENTER_VERTICAL);        
        
        btn = wx.Button(self, -1, u"测试")
        self.Bind(wx.EVT_BUTTON, self.OnTestData, btn);
        gridSizer.Add(btn, pos=(2, 2), size=(1,1), flag=wx.ALIGN_CENTER_VERTICAL);     
        
        #工具条
        self.toolbar = matplotlib.backends.backend_wx.NavigationToolbar2Wx(self.canvas);
        self.toolbar.Realize()
        gridSizer.Add(self.toolbar, pos=(2, 3), size=(1,colTotal-3), flag=wx.EXPAND|wx.ALIGN_CENTER_VERTICAL);
        
      
        
        #Global.SerialGeniusPort.SendAppend(self.dataBuffer)

        #设置变宽信息
        gridSizer.AddGrowableCol(colTotal-1);
        gridSizer.AddGrowableRow(1);


        ############# 结束布局 ###########
        self.SetSizer(gridSizer);
        self.SetAutoLayout(True);
        
        ############# 结束布局 ###########
        
        self.dataAxes_H, = self.axes.plot([], [],color='blue', linestyle='-', marker='.',markerfacecolor='blue', markersize=2);
        self.dataAxes_L, = self.axes.plot([], [],color='red', linestyle='-', marker='.',markerfacecolor='red', markersize=2);
        self.dataAxes_Line_H, = self.axes.plot([], [],color='blue', linestyle='-',linewidth=3.0, marker='.',markerfacecolor='red', markersize=0);
        self.dataAxes_Line_L, = self.axes.plot([], [],color='red', linestyle='-',linewidth=3.0, marker='.',markerfacecolor='red', markersize=0);
        self.axes.grid(True);
        
        self.datax_H = [];
        self.datay_H = [];
        self.datax_L = [];
        self.datay_L = [];
        self.data_angle_H = ANGLE_EMPTY;
        self.data_angle_L = ANGLE_EMPTY;
        
        '''
        import struct;
        import random;
        f = open('rehoodetectordata.bin', 'wb')
        f.write('\xAA');
        f.write('\xAA');
        f.write('\xAA');
        f.write('\xAA');
        f.write('\x04');
        f.write('\x00');
        for i in range(1024*8):
            f.write(struct.pack('B',random.randint(10,99)));
        f.close()
        '''
    
    #新增串口数据，被串口接收所调用
    # AA AA AA AA
    # Angle_H Angle_H
    # DataLen_H DataLen_L
    # Data...
    def RecvData(self, data):
        self.dataBuffer.extend(data);
        if len(self.dataBuffer) < 10:
            return;
        
        if ( self.dataBuffer[0]==0xAA and 
             self.dataBuffer[1]==0xAA and 
             self.dataBuffer[2]==0xAA and 
             self.dataBuffer[3]==0xAA ):
            
            # 角度 高频
            valueH=self.dataBuffer[4];
            valueL=self.dataBuffer[5];
            self.data_angle_H=(valueH<<8)|valueL;
            
            # 角度 低频
            valueH=self.dataBuffer[6];
            valueL=self.dataBuffer[7];
            self.data_angle_L=(valueH<<8)|valueL;
            
            # 数据长度
            valueH=self.dataBuffer[8];
            valueL=self.dataBuffer[9];
            dataLen=(valueH<<8)|valueL;
            # 最大长度判断
            if dataLen > 10240:
                self.dataBuffer = [];
                return;
            
            if len(self.dataBuffer) < 10 +dataLen*8:
                return;
            if DEBUG:
                print("Data full "+str(dataLen));
            
            for i in range(0,10):
                self.dataBuffer.pop(0);
            
            self.datax_H=[];
            self.datay_H=[];
            self.datax_L=[];
            self.datay_L=[];
        
            index = 6;
            for i in range(dataLen):
                for types in range(4):
                    valueH=self.dataBuffer.pop(0);
                    valueL=self.dataBuffer.pop(0);
                    value=(valueH<<8)|valueL;
                    if value>0x7FFF:
                        value=value-0x10000;
                                
                    if types==0:
                        self.datax_H.append(value);
                    elif types==1:
                        self.datay_H.append(value);
                    elif types==2:
                        self.datax_L.append(value);
                    elif types==3:
                        self.datay_L.append(value);
                        
            self.changed = True;
        else:
            while len(self.dataBuffer)>4 and ( self.dataBuffer[0]!=0xAA or
                                               self.dataBuffer[1]!=0xAA or 
                                               self.dataBuffer[2]!=0xAA or 
                                               self.dataBuffer[3]!=0xAA ):
                self.dataBuffer.pop(0);
            
    
    #清空数据
    def OnClearData(self, event):
        self.datax_H=[];
        self.datay_H=[];
        self.datax_L=[];
        self.datay_L=[];
        self.data_angle_H = ANGLE_EMPTY;
        self.data_angle_L = ANGLE_EMPTY;
        self.changed = True

    #重绘函数
    def OnPaint(self, event):
        self.canvas.draw();

    def PlotData(self, evt=None):
                
        if DEBUG:
            print(time.strftime('timer_%Y%m%d_%H_%M_%S',time.localtime(time.time())));
        
        if not self.changed:
            return;
        
        self.changed = False;
        
        self.dataAxes_H.set_data(self.datax_H, self.datay_H);
        self.dataAxes_L.set_data(self.datax_L, self.datay_L);
        
        legend = [u'High', u'Low' ];        
        
        if self.data_angle_H == ANGLE_EMPTY:
            self.dataAxes_Line_H.set_data([],[]);            
        else:
            angle = self.data_angle_H * math.pi / 180.0;
            self.dataAxes_Line_H.set_data([-10000*math.cos(angle),10000*math.cos(angle)],
                                        [-10000*math.sin(angle),10000*math.sin(angle)]);
            legend.append(str(self.data_angle_H)+u' °');      
        
        if self.data_angle_L == ANGLE_EMPTY:
            self.dataAxes_Line_L.set_data([],[]);            
        else:
            angle = self.data_angle_L * math.pi / 180.0;
            self.dataAxes_Line_L.set_data([-10000*math.cos(angle),10000*math.cos(angle)],
                                        [-10000*math.sin(angle),10000*math.sin(angle)]);
            legend.append(str(self.data_angle_L)+u' °');
        
        self.axes.legend(legend);
        
        if DEBUG:
            print(time.strftime('update_%Y%m%d_%H_%M_%S',time.localtime(time.time())));
        
        if self.autoScale:
            if len(self.datax_H)>0 and len(self.datay_H) and len(self.datax_L)>0 and len(self.datay_L)>0:
                
                minv = min(min(self.datax_H),min(self.datax_L));
                maxv = max(max(self.datax_H),max(self.datax_L));
                if minv or maxv:
                    if minv == maxv:
                        maxv = minv + 1;
                    if minv < -7000:
                        minv = -9000
                    if maxv > 7000:
                        maxv = 9000
                else:
                    minv = -9000
                    maxv = 9000
                self.axes.set_xlim(minv,maxv);
                
                minv = min(min(self.datay_H),min(self.datay_L));
                maxv = max(max(self.datay_H),max(self.datay_L));
                if minv or maxv:
                    if minv == maxv:
                        maxv = minv + 1;
                    if minv < -7000:
                        minv = -9000
                    if maxv > 7000:
                        maxv = 9000
                else:
                    minv = -9000
                    maxv = 9000
                self.axes.set_ylim(minv,maxv);
                
            else:
                self.axes.set_xlim(-9000,+9000);
                self.axes.set_ylim(-9000,+9000);
                
            
        try:
            self.canvas.draw()
        except:
            pass

    def OnUpdateData(self, event):
        if Global.SerialGeniusPort and Global.SerialGeniusPort.running:
            data = [];
            sendStr = 'DISP EAD\r\n';
            for i in range(0,len(sendStr)):
                data.append(ord(sendStr[i]));        
            Global.SerialGeniusPort.SendAppend(data);
        else:
            wx.MessageBox(u'请先打开串口',u'提示');
    
    def OnTestData(self, event):
        if Global.SerialGeniusPort and Global.SerialGeniusPort.running:

            # send string
            data = [];
            sendStr = 'string to send';
            for i in range(0,len(sendStr)):
                data.append(ord(sendStr[i]));        
            Global.SerialGeniusPort.SendAppend(data);
            
            '''
            # send list
            data=[];
            data.append(0xAA); 
            data.append(0xAA); 
            data.append(0xAA); 
            data.append(0xAA);
            
            data.append(0x00);
            data.append(0x20);
            data.append(0x00);
            data.append(0x40);
            
            data.append(0x04);
            data.append(0x00);
            
            import random;
            for i in range(1024*8):
                data.append(random.randint(0,99));
            
            Global.SerialGeniusPort.SendAppend(data);
            '''
            
        else:
            wx.MessageBox(u'请先打开串口',u'提示');
        
    def on_button_press_event(self, event):
        if 'PAN'==self.axes.get_navigate_mode() or 'ZOOM'==self.axes.get_navigate_mode():
            self.autoScale=False;
        else:
            self.autoScale=True;